/**
 * 
 */
package org.youisoft.summer.evaluator.unit;

import org.youisoft.summer.evaluator.EvaluateException;
import org.youisoft.summer.evaluator.InvokeException;
import org.youisoft.summer.evaluator.UnitEnum;
import org.youisoft.summer.evaluator.context.CalContext;
import org.youisoft.lifecircle.Initilize;
import org.youisoft.summer.evaluator.operator.Operator;
import org.youisoft.summer.evaluator.registry.FunctionRegistry;

/**
 * @author zijiang.jl
 *
 */
public interface VisitorUnit<R,P> extends Initilize {
	
	/**
	 * 
	 * @return
	 */
	public UnitEnum getUnitType();

	/**
	 * 
	 * @param <C>
	 * @param context
	 * @param visitor
	 * @throws InvokeException
	 */
	public <C> void accept(CalContext<C,R,P> context,UnitVisitor<R,P> visitor) throws InvokeException;
	

	/**
	 * 
	 * @param <C>
	 * @param context
	 * @param operator
	 * @return
	 * @throws InvokeException
	 */
	public <C> Operator<?> calculate(CalContext<C,R,P> context,Operator<?> operator) throws InvokeException;
	
	
	/**
	 * 
	 * @param <C>
	 * @param context
	 * @param value
	 * @return
	 * @throws EvaluateException
	 */
	public <C> Operator<?> convertPlaceHolder(CalContext<C,R,P> context,Operator<?> value);
	
	//==========================================
	/**
	 * 
	 * @return
	 */
	public P getProperty();

	/**
	 * 
	 * @param property
	 */
	public void setProperty(P property);

	/**
	 * 
	 * @return
	 */
	public R getResource();

	/**
	 * 
	 * @param resource
	 */
	public void setResource(R resource);
	/**
	 * 
	 * @param obj
	 */
	public void setSource(Object obj);
	
	/**
	 * 
	 * @return
	 */
	public Object getSource();
	
	
	//=============================================
	
	/**
	 * 
	 * @param content
	 */
	public void setContent(String content);
	
	/**
	 * 
	 * @return
	 */
	public String getContent();
	
	/**
	 * 
	 * @param idx
	 */
	public void setLeftIndex(int idx);
	
	/**
	 * 
	 * @return
	 */
	public int getLeftIndex();
	
	/**
	 * 
	 * @return
	 */
	public int getRightIndex();
	
	/**
	 * 
	 * @param idx
	 */
	public void setRightIndex(int idx);
	
	
	//=======================================
	
	/**
	 * 
	 * @return
	 */
	public VisitorUnit<R, P> getParentUnit();

	/**
	 * 
	 * @param parentUnit
	 */
	public void setParentUnit(VisitorUnit<R, P> parentUnit);
	

	
	/**
	 * 
	 * @return
	 */
	public Iterator<VisitorUnit<R, P>> iterator();
	
	
	public interface Iterator<I>{
		
		public UnitEnum hasNext();
		
		public I next();
		
		public int currentPosition();
		
		public int size();
	}
	
	
	public VisitorUnit<R, P> getChildUnit(int index);
	
	/**
	 * 
	 * @param index
	 * @return
	 */
	public Operator<?> getChildValue(int index);
	
	/**
	 * 
	 * @param child
	 */
	public void addChildUnit(VisitorUnit<R, P> child);
	
	/**
	 * 
	 * @param value
	 */
	public void addChildValue(Operator<?> value);
	/**
	 * 
	 * @return
	 */
	public int childSize();

	
	//=============================
	/**
	 * 
	 * @param fName
	 */
	public void setfName(String fName);
	
	/**
	 * 
	 * @return
	 */
	public String getfName();

	
	/**
	 * 
	 * @return
	 */
	public int getFunIndex();

	/**
	 * 
	 * @param funIndex
	 */
	public void setFunIndex(int funIndex);
	
	
	/**
	 * 
	 * @return
	 */
	public FunctionRegistry getRegistry();

	/**
	 * 
	 * @param registry
	 */
	public void setRegistry(FunctionRegistry registry);
}
